package com.jeesit.cloud.spot.web.api_controller.hedging_scheme;

import com.jeesit.cloud.annotation.ModuleLog;
import com.jeesit.cloud.dto.*;
import com.jeesit.cloud.spot.business.impl.IHedgingSchemeBiz;
import com.jeesit.cloud.spot.service.*;
import com.jeesit.cloud.spot.web.api_controller.contract.ContractController;
import com.jeesit.cloud.verify.UserAuthDetail;
import com.jeesit.cloud.constants.LogConstant;
import com.jeesit.cloud.util.ExportExcel;
import com.jeesit.cloud.validate.UpdateAction;
import com.jeesit.cloud.validate.CreateAction;
import com.jeesit.cloud.validate.QueryAction;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.N;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.jeesit.cloud.model.*;

import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Size;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 *   相关接口
 *
 *   @description HedgingScheme 接口
 *   ---------------------------------
 *   @author lss
 *   @date 2024-01-25
 */
@Slf4j
@RestController
@RequestMapping("/api/auth/v1/hedging_scheme")
@Api(tags = {"套保方案"})
public class HedgingSchemeController {

    @Autowired
    private IHedgingSchemeService hedgingSchemeService;
    @Autowired
    private IHedgingSchemeBiz hedgingSchemeBiz;
    @Autowired
    private IHedgingSchemeInstService hedgingSchemeInstService;
    @Autowired
    private IHedgeSchemeAccountService hedgeSchemeAccountService;
    @Autowired
    private IContractSchemaService contractSchemaService;
    @Autowired
    private IContractService contractService;
    @Autowired
    private ContractController contractController;
    @Autowired
    private IGdInventoryRecordService gdInventoryRecordService;

    /**
     * @description 获取分页列表
     * ---------------------------------
     * @author lss
     * @date 2024-01-25
     */
    @ApiOperation("获取分页列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "会话标识", dataType = "String", paramType = "header", required = true),
            @ApiImplicitParam(name = "pageNo", value = "页码", dataTypeClass = Integer.class , paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页行数，最少10条，最多100条", dataTypeClass = Integer.class , paramType = "query", required = true)
    })
    @PostMapping(value = "/hedging_scheme_page")
    public JSONResult<Page<HedgingScheme>> getHedgingSchemePage(Authentication authentication,@Validated(QueryAction.class)HedgingSchemeDto dto) {
        User user = ((UserAuthDetail)authentication.getPrincipal()).getUser();
        Page<HedgingScheme> page=new Page<HedgingScheme>(dto.getPageNo(), dto.getPageSize());
        hedgingSchemeService.page(page,dto);
        JSONResult<Page<HedgingScheme>> res = new JSONResult<>();
        res.setMessage("");
        res.setSuccess(true);
        res.setData(page);
        return res;
    }

    /**
     * @description 获取列表
     * ---------------------------------
     * @author lss
     * @date 2024-01-25
     */
    @ApiOperation("获取列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "会话标识", dataType = "String", paramType = "header", required = true),
            @ApiImplicitParam(name = "size", value = "查询数量，最多查询1000条", dataTypeClass = Integer.class, paramType = "query", required = true)
    })
    @PostMapping(value = "/hedging_scheme_list")
    public JSONResult<HedgingScheme> getHedgingSchemeList(Authentication authentication, @Validated(QueryAction.class)HedgingSchemeDto dto) {
        User user = ((UserAuthDetail)authentication.getPrincipal()).getUser();
        List<HedgingScheme> list = hedgingSchemeService.list(dto.getSize(),dto);
        if(dto.getUuid()!=null){
            for(HedgingScheme it :list){
                HedgingSchemeInstDto hedgingSchemeInstDto = new HedgingSchemeInstDto();
                hedgingSchemeInstDto.setSchemeUuid(it.getUuid());
                List<HedgingSchemeInst> hedgingSchemeInsts = hedgingSchemeInstService.list(0, hedgingSchemeInstDto);
                it.setHedgingSchemeInstDtos(hedgingSchemeInsts);//合约明细
                HedgeSchemeAccountDto hedgeSchemeAccountDto = new HedgeSchemeAccountDto();
                hedgeSchemeAccountDto.setSchemeUuid(it.getUuid());
                List<HedgeSchemeAccount> hedgeSchemeAccounts = hedgeSchemeAccountService.list(0, hedgeSchemeAccountDto);
                it.setHedgeSchemeAccounts(hedgeSchemeAccounts);
                ContractSchemaDto contractSchemaDto = new ContractSchemaDto();
                contractSchemaDto.setSchemaUuid(it.getUuid());
                List<ContractSchema> contractSchemas = contractSchemaService.list(0, contractSchemaDto);
                Long[] contractUuids = contractSchemas.stream().map(ContractSchema::getContractUuid).toArray(Long[]::new);
                if(contractUuids.length>0) {
                    ContractDto contractDto = new ContractDto();
                    contractDto.setUuids(contractUuids);
                    List<Contract> contracts = contractService.list(0, contractDto);
                    for(Contract its :contracts){
                        its.setTopContract(its.getMaterialTopName()+its.getIsContract());
                        contractController.sumWeight(its);//计算合同量
                    }
                    it.setContractDtos(contracts);//合同数据
                    Map<String,List<Contract>> conGroup = contracts.stream().collect(Collectors.groupingBy(Contract::getTopContract));
                    List<FurSpotVoDto> furSpotVoDtos = new ArrayList<>();
                    //期现合并数据
                    for(String key : conGroup.keySet()){
                        List<Contract> contractList = conGroup.get(key);
                        FurSpotVoDto furSpotVoDto = new FurSpotVoDto();
                        furSpotVoDto.setFurPosition(0);
                        furSpotVoDto.setFurSpot(0d);
                        furSpotVoDto.setFurWeight(0d);
                        furSpotVoDto.setSpotOpen(0D);
                        for(Contract its: contractList){
                            if(its.getIsContract()) {
                                furSpotVoDto.setDirection("多头");
                                furSpotVoDto.setPurSale("销售");
                            }else {
                                furSpotVoDto.setDirection("空头");
                                furSpotVoDto.setPurSale("采购");
                            }
                            furSpotVoDto.setCatalogName(its.getCatalogName());
                            furSpotVoDto.setSpotOpen(its.getContractWeight()+furSpotVoDto.getSpotOpen());
                        }
                        furSpotVoDtos.add(furSpotVoDto);
                    }
                    it.setFurSpotVoDtos(furSpotVoDtos);
                    //批号数据
                    String[] purNumber = contracts.stream().map(Contract::getContractNumber).toArray(String[]::new);
                    GdInventoryRecordDto gdInventoryRecordDto = new GdInventoryRecordDto();
                    gdInventoryRecordDto.setGoodsContractolds(purNumber);
                    it.setGdInventoryRecords(gdInventoryRecordService.list(0,gdInventoryRecordDto));
                }
            }
        }
        JSONResult<HedgingScheme> res = new JSONResult<>();
        res.setMessage("");
        res.setSuccess(true);
        res.setDatas(list);
        return res;
    }


    /**
     * @description 导出列表
     * ---------------------------------
     * @author lss
     * @date 2024-01-25
     */
    @ApiOperation("导出列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "会话标识", dataType = "String", paramType = "header", required = true)
    })
    @PreAuthorize("hasAnyAuthority('HedgingScheme_Export','SUPER_ADMIN')")
    @PostMapping(value = "/hedging_scheme_export")
    public void export(HttpServletResponse response,Authentication authentication, @Validated(QueryAction.class)HedgingSchemeDto dto) {
        User user = ((UserAuthDetail)authentication.getPrincipal()).getUser();
        List<HedgingScheme> datas = hedgingSchemeService.list(0,dto);
        String[] header = new String[]{"业务部门名称","业务部门uuid","方案名称","业务类型 0自营套保 1","业务员姓名","业务员uuid","交易员姓名","交易员uuid","风控人姓名","风控人uuid","执行状态 0为执行 1执行中 2已完结","备注","品类","品种","合约代码","最大手数","现货敞口","我方盈亏","客户盈亏","创建人姓名","创建时间","创建人uuid","修改人姓名","修改时间","修改人uuid","审批时间","审批人姓名","审批人uuid","",""};
        List<List<Object>> list = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        DecimalFormat df = new DecimalFormat("0.00");
        for(HedgingScheme it : datas){
            List<Object> data = new ArrayList<>();
            data.add(it.getBizOrgName());
            data.add(it.getBizOrgUuid());
            data.add(it.getName());
            data.add(it.getBusinessType());
            data.add(it.getSalesmanName());
            data.add(it.getSalesmanUuid());
            data.add(it.getTraderName());
            data.add(it.getTraderUuid());
            data.add(it.getRiskName());
            data.add(it.getRiskUuid());
            data.add(it.getExecutingState());
            data.add(it.getRemark());
            data.add(it.getCatalog());
            data.add(it.getProduct());
            data.add(it.getInstrumentCode());
            data.add(it.getMaxPosition());
            data.add(Optional.ofNullable(it.getSpotWeight()).map(s->df.format(s)).orElse(""));
            data.add(Optional.ofNullable(it.getProfit()).map(s->df.format(s)).orElse(""));
            data.add(Optional.ofNullable(it.getClientProfit()).map(s->df.format(s)).orElse(""));
            data.add(it.getAddUserName());
            data.add(Optional.ofNullable(it.getAddTime()).map(s->sdf.format(s)).orElse(""));
            data.add(it.getAddUserUuid());
            data.add(it.getModUserName());
            data.add(Optional.ofNullable(it.getModTime()).map(s->sdf.format(s)).orElse(""));
            data.add(it.getModUserUuid());
            data.add(Optional.ofNullable(it.getCheckTime()).map(s->sdf.format(s)).orElse(""));
            data.add(it.getCheckUserName());
            data.add(it.getCheckUserUuid());
            data.add(it.getDeleted());
            list.add(data);
        }
        ExportExcel excel = new ExportExcel();
        excel.setName("");
        excel.exportToExcel(response,header,list,0);
    }

    /**
     * @description 新建
     *
     * @author lss
     * @date 2024-01-25
     */
    @ApiOperation("新建")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "会话标识", dataType = "String", paramType = "header", required = true)
    })
    @PreAuthorize("hasAnyAuthority('HedgingScheme_Add','SUPER_ADMIN')")
    @ModuleLog("HedgingScheme")
    @PostMapping("/hedging_scheme_add")
    public JSONResult<HedgingScheme> saveNewEntity(HttpServletRequest request,Authentication authentication, @Validated(CreateAction.class) HedgingSchemeDto entity){
        User user = ((UserAuthDetail)authentication.getPrincipal()).getUser();
        JSONResult<HedgingScheme> res= hedgingSchemeBiz.saveData(user,null,entity);
        if(res.isSuccess()){
            request.setAttribute(LogConstant.LOG_KEY,new LogInfo(user.getId(), "保存，数据ID:"+res.firstData().getUuid()));
        }
        return res;
    }

    /**
     * @description 更新
     *
     * @author lss
     * @date 2024-01-25
     */
    @ApiOperation("更新 ")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "会话标识", dataType = "String", paramType = "header", required = true)
    })
    @PreAuthorize("hasAnyAuthority('HedgingScheme_Modify','SUPER_ADMIN')")
    @ModuleLog("HedgingScheme")
    @PostMapping("/hedging_scheme_edit")
    public JSONResult<HedgingScheme> saveEditEntity(HttpServletRequest request,Authentication authentication,@Validated(UpdateAction.class) HedgingSchemeDto entity){
        User user = ((UserAuthDetail)authentication.getPrincipal()).getUser();
        JSONResult<HedgingScheme> res= hedgingSchemeBiz.saveData(user,entity.getUuid(),entity);
        if(res.isSuccess()){
            request.setAttribute(LogConstant.LOG_KEY,new LogInfo(user.getId(), "更新，数据ID:"+res.firstData().getUuid()));
        }
        return res;
    }

    private JSONResult<HedgingScheme> saveData(User user,Long id,HedgingSchemeDto entity){
        JSONResult<HedgingScheme> res = new JSONResult<>();
        HedgingScheme it = new HedgingScheme();
        if(id==null){
            it.setDeleted(false);
        } else {
            it = hedgingSchemeService.getById(entity.getUuid());
        }
        it.setBizOrgName(entity.getBizOrgName());
        it.setBizOrgUuid(entity.getBizOrgUuid());
        it.setName(entity.getName());
        it.setBusinessType(entity.getBusinessType());
        it.setSalesmanName(entity.getSalesmanName());
        it.setSalesmanUuid(entity.getSalesmanUuid());
        it.setTraderName(entity.getTraderName());
        it.setTraderUuid(entity.getTraderUuid());
        it.setRiskName(entity.getRiskName());
        it.setRiskUuid(entity.getRiskUuid());
        it.setExecutingState(entity.getExecutingState());
        it.setRemark(entity.getRemark());
        it.setCatalog(entity.getCatalog());
        it.setProduct(entity.getProduct());
        it.setInstrumentCode(entity.getInstrumentCode());
        it.setMaxPosition(entity.getMaxPosition());
        it.setSpotWeight(entity.getSpotWeight());
        it.setProfit(entity.getProfit());
        it.setClientProfit(entity.getClientProfit());
        it.setAddUserName(entity.getAddUserName());
        it.setAddUserUuid(entity.getAddUserUuid());
        it.setModUserName(entity.getModUserName());
        it.setModUserUuid(entity.getModUserUuid());
        it.setCheckTime(entity.getCheckTime());
        it.setCheckUserName(entity.getCheckUserName());
        it.setCheckUserUuid(entity.getCheckUserUuid());
        hedgingSchemeService.saveOrUpdate(it);
        res.setData(it);
        res.setSuccess(true);
        res.setMessage("保存成功");
        return res;
    }


    /**
     * @description 删除
     *
     * @author lss
     * @date 2024-01-25
     */
    @ApiOperation("删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "会话标识", dataType = "String", paramType = "header", required = true),
            @ApiImplicitParam(name = "ids", value = "删除id（支持批量删除）", dataTypeClass = Long.class , allowMultiple = true,paramType = "query", required = true),
    })
    @PreAuthorize("hasAnyAuthority('HedgingScheme_Remove','SUPER_ADMIN')")
    @ModuleLog("HedgingScheme")
    @PostMapping("hedging_scheme_del")
    public JSONResult<Void> delEntity(HttpServletRequest request,Authentication authentication,@Size(min=1,max=50,message = "请选择要删除数据") Long[] ids) throws Exception{
        User user = ((UserAuthDetail)authentication.getPrincipal()).getUser();
        JSONResult<Void> res = new JSONResult<>();
        for(int i=0;i<ids.length;i++){
            HedgingScheme it = hedgingSchemeService.getById(ids[i]);
            hedgingSchemeService.removeById(it.getUuid());
        }
        request.setAttribute(LogConstant.LOG_KEY,new LogInfo(user.getId(), "删除，数据ID:" + StringUtils.join(ids)));
        res.setMessage("删除成功");
        res.setSuccess(true);
        return res;
    }

}

